#include <stdio.h>
#include <stdlib.h>
#include "sds.h"
#include "sdsalloc.h"
#include "testhelp.h"
#include <string.h>
/**
 * 使用redis之父的一个simple dynamic string C库的代码处理常见的字符串，下面原始库、作者的个人网站信息
 * https://github.com/antirez/sds
 * http://invece.org/
 * http://antirez.com/
 * @return
 */
int main() {
    struct __attribute__ ((__packed__)) arr_pointer{
        unsigned int age;//4字节
        int *int_pointer;//8字节
        int arr[4];//16字节
    };
    struct arr_pointer instance = {.age=18,.int_pointer = NULL,.arr={1,2,3,4}};
    printf("%d\n", sizeof(struct arr_pointer));
    printf("%d\n", sizeof(instance));

    printf("***************************************\n");

    struct __attribute__ ((__packed__)) arr_pointer_other{
        unsigned int age;//4字节
        char *char_pointer;//8字节
        int *int_pointer;;//8字节
        char arr[];//0字节(不计入，可变)
    };
    int money = 100;
    struct arr_pointer_other instance_other = {.age=18,.char_pointer = "HSX is smart!",.int_pointer=&money};
    printf("%d\n", sizeof(struct arr_pointer_other));
    void *struct_pointer = &instance_other;
    char *my_sds = (char*)struct_pointer + 20;
    my_sds[0] = 'H';
    my_sds[1] = 'S';
    my_sds[2] = 'J';
    my_sds[3] = '\0';
    printf("%d\n", instance_other.age);
    printf("%s\n", instance_other.char_pointer);
    printf("%d\n", *(instance_other.int_pointer));
    printf("%s\n", instance_other.arr);
    printf("%d\n", sizeof(instance_other));


//    测试
//    test_cond("Check if 1 == 1", 1 == 1);
//    test_cond("Check if 5 > 10", 5 > 10);
//    test_report();
//    unsigned char flags = '\0';
//    printf("%d\n",flags);
//    flags = '0';
//    printf("%d\n",flags);
//
//
////    C不老实，不使用变量自己变成int
//    printf("%d\n", sizeof flags);
//    printf("%d\n", sizeof('0'));
//    printf("%d",((8)>>SDS_TYPE_BITS));

//      unsigned char flags = 1;
//      printf("%d\n",flags<<SDS_TYPE_BITS);
//      printf("%ld\n",LONG_MAX);
//      printf("%lld\n",LLONG_MAX);
//        sds s = sdsnew(SDS_NOINIT);
//        printf("%s\n",s);



//    说明：1<<5 = 1 * 2^5
//    if (5 < 1<<5)
//        printf("%d\n",5);
//    printf("%d",0 | (3 << SDS_TYPE_BITS));


//     取消编译器自作聪明的对齐，浪费空间
//     struct __attribute__ ((__packed__)) init_empty{
//         uint32_t len;
//         unsigned char flag;
//         char buf[];
//     };
//    struct  init_empty_no_packed{
//        uint32_t len;
//        unsigned char flag;
//        char buf[];
//    };
//     printf("%d\n", sizeof(struct  init_empty));
//     printf("%d\n", sizeof(struct  init_empty_no_packed));

//    使用sdslen
//    sds my_string = sdsnewlen("abc",3);
//    printf("%s\n", my_string);
//    printf("%d\n", sdslen(my_string));
//    sdsfree(my_string);


//    sds s = sdsnewlen("A\0\0B",4);
//    printf("%s\n", s);
//    printf("%d\n", (int) sdslen(s));


//    打印
//    sds s;
//    int a = 10, b = 20;
//    s = sdsnew("The sum is: ");
////    s = sdscatprintf(s,"%d+%d = %d",a,b,a+b);
//    s = sdscatfmt(s,"%i+%i = %i",a,b,a+b);
//    printf("%s\n", s);

//    long转字符串
//    sds s = sdsfromlonglong(10000);
//    printf("%d\n", (int) sdslen(s));
//    printf("%s\n", s);

//    trim使用
//    sds s = sdsnew("         my string\n\n  ");
//    sdstrim(s," \n");//trim ： space \n
//    printf("-%s-\n",s);

//    range使用，类似：subtring
//    sds s = sdsnew("Hello World!");
//    sdsrange(s,6,-1);
//    printf("-%s-\n",s);
//    sdsrange(s,0,-2);


//    使用复制copy
//    sds s = sdsnew("Hello World!");
//    s = sdscpylen(s,"Hello Superman!",10);
//    printf("-%s-\n",s);


//    使用split
//    sds *tokens;
//    int count, j;
//
//    sds line = sdsnew("Hello -World!");
//    tokens = sdssplitlen(line,sdslen(line)," -",2,&count);
//
//    for (j = 0; j < count; j++)
//        printf("%s\n", tokens[j]);
//    sdsfreesplitres(tokens,count);


//    使用join
//    const int len = 3;
//    char *tokens[3] = {"foo","bar","zap"};
//    sds s = sdsjoin(tokens, /*sizeof(tokens) / sizeof (char *)*/ 3,"|");
//    printf("%s\n", s);
//    //释放allocator内存
//    sdsfree(s);
//


//    使用cat
//    s = sdsnew("Ladies and gentlemen");
//    s = sdscat(s,"... welcome to the C language.");
//    printf("%d\n", (int) sdsAllocSize(s));
//    printf("%s\n",s);
//    s = sdscat(s,"... welcome again to the C language.");
//    printf("%d\n", (int) sdsAllocSize(s));
//    printf("%s\n",s);
//
//    s = sdsRemoveFreeSpace(s);
//    printf("%d\n", (int) sdsAllocSize(s));
//    //释放allocator内存
//    sdsfree(s);



//  测试内存溢出
//    while (1){
//        sds empty_s = sdsempty();
//        printf("%d\n", (int) sdsAllocSize(empty_s));
//        printf("%d\n", (int) sdslen(empty_s));
//        empty_s = sdsMakeRoomFor(empty_s,100);
////    empty_s = sdscat(empty_s,"redis`s parent.");
//        printf("%d\n", (int) sdsAllocSize(empty_s));
//        printf("%d\n", (int) sdslen(empty_s));
//
//        //导致empty_s的是sds堆内存指针丢失，无法释放内存；---补救：sdsfree(empty_s);
//        sdsfree(empty_s);
//
//        empty_s = "memery leak.";
//        printf("%s\n",empty_s);
//    }



//   自制一个sds
//   数组不指定大小或者初始化
//    struct __attribute__ ((__packed__)) char_struct{
//        uint32_t allocator;
//        char buf[];
//    };
//    const unsigned int SIZE_BUFF = 100;
//    const char *init = "this is my first sds(simple dynamic string).";
//    unsigned int init_size = (unsigned int)strlen(init);
////    while (1){
//        //100个字节的char数组 + 1个'\0'
//        unsigned int head_size = (unsigned int)(sizeof(struct char_struct));
//        printf("%d\n", head_size);
//        unsigned int size = (head_size)+SIZE_BUFF+1;
//        void *sh = s_malloc(size);
//        memset(sh, 0, size);
//        *((uint32_t*)sh) = size;
//        char* msds = (char*)sh + head_size;
//        memcpy(msds, init, init_size);
//        msds[init_size] = '\0';
//
//        struct char_struct* p_struct = ((struct char_struct*)(msds - head_size));
//        printf("size=%d,\nstring=%s\n",(unsigned int)(p_struct->allocator),p_struct->buf);
//        printf("size=%d,\nstring=%s\n",(unsigned int)(*(uint32_t*)(msds - head_size)),msds);
//
//        s_free(msds-head_size);
////    }


    //16进制
//    char a = 0x10;
//    int b = 0x00000010;
//
//    printf("value of a: %X [%d]\n",a,a);
//    printf("value of b: %X [%d]\n",b,b);
    return EXIT_SUCCESS;
}
